﻿using System;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.UI;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using Slam.FieldTypes;
using SlamCms.Configuration;
using SlamCms.SharePoint.Core;
using SlamCms.Data;
using Slam.SharePoint;
using SlamCms.SharePoint.SlamProfiles.ContentItem;
using System.Collections.Specialized;
using System.Reflection;
using SlamCms.SharePoint.Core.Extensions;
using SlamCms.Common;
using Slam.Events;

namespace SlamCms.SharePoint.FieldTypes
{
	[SlamFieldAction(ActionType = SlamFieldActionType.Load, Synchronous = true, DisplayName = "HideEventRecurrenceControls")]
	public class HideEventRecurrenceControlsAction : ISlamFieldAction
	{
		public void Run(SlamFieldActionContext context)
		{	
			Page page = context.HttpContext.Handler as Page;

			if (page != null)
			{
				page.ClientScript.RegisterClientScriptInclude("jquery", page.ResolveUrl("~/_layouts/inc/jquery-1.6.2.min.js"));

				string[] fields = new string[] { "Recurrence", "Workspace" };
				page.ClientScript.RegisterClientScriptBlock(this.GetType(), "HideFields", getScriptToHideField(fields));
			}
		}

		private string getScriptToHideField(string[] fieldTitle)
		{
			string function = @"function hideField(fieldTitle)
							{
							var theRows = document.getElementsByTagName('TR');
							var r = 0;
							var strTitle = '';
							while (r < theRows.length)
							{ 
								try
								{
									strTitle = theRows[r].innerText || theRows[r].textContent;
									strTitle = strTitle.replace(/\n|\r|\t|\^ /g,'');
									if (strTitle.search(fieldTitle) == 0 )
									{ 
										theRows[r].style.display = 'none'; 
									}
								}
								catch(err){}
								r+=1;
							}
							};";

			StringBuilder builder = new StringBuilder("");
			foreach (string title in fieldTitle)
			{
				builder.Append(String.Format("hideField('{0}');", title));
			}

			return String.Format("<script type=\"text/javascript\">{0};$('document').ready(function a(){{{1}}});{0}{1}</script>", function, builder.ToString());
		}
	}

	[SlamFieldAction(ActionType = SlamFieldActionType.Load, Synchronous = true, DisplayName = "HideContentApprovalNote")]
	public class HideContentApprovalNoteAction : ISlamFieldAction
	{
		public void Run(SlamFieldActionContext context)
		{
			Page page = context.HttpContext.Handler as Page;

			if (page != null)
			{
				string include = "<style type=\"text/css\">.ms-informationbar{ display:none}</style>";
				if (!page.Header.Controls.Cast<Control>().OfType<LiteralControl>().Any(c => c.Text == include))
				{
					page.Header.Controls.Add(new LiteralControl(include));
				}
			}
		}
	}

	[SlamFieldAction(ActionType = SlamFieldActionType.Load, Synchronous = true, DisplayName = "HideEditFormInformationBar")]
	public class HideEditFormInformationBarAction : ISlamFieldAction
	{	
		public void Run(SlamFieldActionContext context)
		{
			Page page = context.HttpContext.Handler as Page;

			if (page != null)
			{
				page.ClientScript.RegisterClientScriptInclude("jquery", page.ResolveUrl("~/_layouts/inc/jquery-1.6.2.min.js"));

				StringBuilder builder = new StringBuilder("");
				builder.Append("$('.ms-informationbar').hide();");
				builder.Append("var saveButtons = $('input[type=button][value=\"Save\"]');");
				builder.Append("for(i=0;i<saveButtons.length;i++){saveButtons[i].value = 'Save Draft';}");

				if (SPContext.Current != null && SPContext.Current.ListItem != null)
				{
					string deleteText = "Delete<br>Item";
					string deleteConfirmationMessage = "Are you sure you want to send the item(s) to the site Recycle Bin?";
					string status = SPContext.Current.ListItem.GetPublishingStatus();

					if (status == SlamProfiles.ContentItem.ContentItemStatus.Live.Name)
					{
						deleteText = "Retire<br>Item";
						deleteConfirmationMessage = "Are you sure you would like to retire this item?";
					}
					else if (status == SlamProfiles.ContentItem.ContentItemStatus.Modified.Name || status == SlamProfiles.ContentItem.ContentItemStatus.PendingApprovalModified.Name)
					{
						deleteText = "Delete<br>Draft";
						deleteConfirmationMessage = "Are you sure you would like to delete the current draft of this item?";
					}
					else if (status == SlamProfiles.ContentItem.ContentItemStatus.Retired.Name)
					{
						builder.Append(" $('a[id=\"Ribbon.ListForm.Edit.Actions.DeleteItem-Large\"]').attr('style', 'display:none;'); ");
					}

					if (deleteText != "Delete<br>Item")
						builder.Append(" $('a[id=\"Ribbon.ListForm.Edit.Actions.DeleteItem-Large\"]').find('.ms-cui-ctl-largelabel').html('" + deleteText + "'); L_STSRecycleConfirm_Text = '" + deleteConfirmationMessage + "'; ");
				}
				string script = String.Format("<script type=\"text/javascript\">$('document').ready(function a(){{{0}}});</script>", builder.ToString());
				page.ClientScript.RegisterClientScriptBlock(this.GetType(), "HideInformationBar", script);
			}
		}
	}

	[SlamFieldAction(ActionType = SlamFieldActionType.Load, Synchronous = true, DisplayName = "RedirectToFrontEndUrl")]
	public class RedirectToFrontEndUrlAction : ISlamFieldAction
	{
		public void Run(SlamFieldActionContext context)
		{
			Page page = HttpContext.Current.Handler as Page;
			SPList list = context.SPContext.List;
			if (page != null && (!list.NavigateForFormsPages || !page.IsPostBack))
			{
				SPListItem listItem = SPContext.Current.ListItem;
				string slamId = Convert.ToString(listItem["SLAM ID"]).Replace("-p", "");

				if (String.IsNullOrEmpty(slamId))
				{
					var slamIdField = SlamIdFieldControl.GetCurrent(page);
					if (slamIdField != null)
						slamId = Convert.ToString(slamIdField.Value);
				}
				if (!String.IsNullOrEmpty(slamId))
				{
					string redirectUrl = ConfigurationManager.Environment.DefaultApplication.FrontEndUrl.TrimEnd('/') + "/link/" + slamId + "?preview=true";
					if (page.Request.QueryString["IsDlg"] != null)
					{
						Slam.SlamContext.Get(listItem.ParentList).Actions.Register(Slam.SlamEvent.PostSave, actionListItem =>
						{
							HttpContext.Current.Response.Write(String.Format("<script type='text/javascript'>window.top.location.href = '{0}'</script>", redirectUrl));
							HttpContext.Current.Response.Flush();
							HttpContext.Current.Response.End();
						});
					}
					else
					{
						redirectUrl = ("/" + SPContext.Current.Site.ServerRelativeUrl.TrimStart('/')).TrimEnd('/') + HttpUtility.UrlEncode("/_layouts/SlamCMS/Redirector.aspx?to=frontend&ReturnUrl=" + redirectUrl);
						NameValueCollection queryStringCollection = HttpUtility.ParseQueryString(page.Request.Url.Query);
						queryStringCollection.Add("SlamId", Convert.ToBase64String(Encoding.UTF8.GetBytes(slamId)));
						queryStringCollection["Source"] = redirectUrl;

						if (SPContext.Current.FormContext.FormMode == SPControlMode.New && page.Request.QueryString["SlamId"] == null)
						{
							page.Response.Redirect(page.Request.Url.AbsolutePath + "?" + queryStringCollection.ToString());
						}
						else if (SPContext.Current.FormContext.FormMode == SPControlMode.Edit && page.Request.QueryString["Source"] == null || (page.Request.QueryString["Source"] != null && page.Request.QueryString["Source"] != redirectUrl))
						{
							page.Response.Redirect(page.Request.Url.AbsolutePath + "?" + queryStringCollection.ToString());
						}
					}
				}
			}
		}
	}

	[SlamFieldAction(ActionType = SlamFieldActionType.PostSave, Synchronous = true, DisplayName = "SetContentItemExpiration")]
	public class SetContentItemExpirationAction : ISlamFieldAction
	{
		public void Run(SlamFieldActionContext context)
		{
			SlamCmsContext.SharePoint.WithElevatedPrivileges().SiteCollection(context.FormUrl).Site((s, sc) =>
			{
				SPList list = s.GetListFromUrl(context.FormUrl);
				if (!context.SlamId.IsNullOrEmpty())
				{
					SPListItem listItem = list.GetItemBySlamId(context.SlamId);
					if (listItem != null)
					{
						var contentType = listItem.GetSlamCmsContentType();
						if (contentType != null && contentType.ExpirationPeriod.HasValue)
							SlamCmsContext.Data.Database.ExecuteNonQuery(@"update ContentItem
														set ExpirationDate = case when VerifiedDate is null then DATEADD(day,{0},CreatedDate) else DATEADD(day,{0},VerifiedDate) end
														where ExpirationDate is null and PrimaryContentItemID = '{1}'".F(contentType.ExpirationPeriod.Value, context.SlamId.Replace("-p", "")));
					}
				}
			});
		}
	}

	[SlamFieldAction(ActionType = SlamFieldActionType.Load, Synchronous = true, DisplayName = "RegisterDocumentReplacementUploadField")]
	public class RegisterDocumentReplacementUploadFieldAction : ISlamFieldAction
	{
		public void Run(SlamFieldActionContext context)
		{
			if (SPContext.Current.FormContext.FormMode == SPControlMode.Edit)
			{
				if (context.HttpContext.Handler is Page && !((Page)context.HttpContext.Handler).IsPostBack)
				{
					context.SPContext.ListItem[context.Field.Title] = "";
				}

				//Document Replacement can only be performed by the EnhancedFileUploadFieldControl
				if (context.FieldControl is EnhancedFileUploadFieldControl)
				{
					// Register postsave action to replace the SPFile of the item.
					Slam.SlamContext.Get(context.SPContext.List).Actions.Register(Slam.SlamEvent.PostSave, actionListItem =>
					{
						if (actionListItem.File != null && actionListItem.Fields.ContainsFieldWithStaticName(context.Field.StaticName))
						{
							string fieldValue = Convert.ToString(actionListItem[context.Field.Title]);
							if (!fieldValue.IsNullOrEmpty())
							{	
								EnhancedFileUploadFieldControl control = context.FieldControl as EnhancedFileUploadFieldControl;
								if(control.StorageMode == "Document Library")
								{
									byte[] replacementFileBytes = null;
									string replacementFileName = string.Empty;
									DateTime replacementFileModified = DateTime.MinValue;

									SlamCmsContext.SharePoint.WithElevatedPrivileges().SiteCollection(actionListItem.Web.Site.ID, sc =>
									{
										foreach (SPWeb site in sc.AllWebs)
										{
											SPList saveList = null;
											try
											{
												saveList = site.Lists.GetList(new Guid(control.SaveDocumentLibrary), false);
											}
											catch { }

											if (saveList != null)
											{
												var file = site.GetFile(fieldValue);
												if (file != null)
												{
													replacementFileBytes = file.OpenBinary();
													replacementFileName = file.Name;
													replacementFileModified = file.TimeLastModified;
												}
											}
											site.Dispose();
										}
									});

									if (replacementFileBytes != null)
									{
										bool fileNameChanged = !actionListItem.File.Name.Equals(replacementFileName);
										EventUtility eventUtility = new EventUtility();
										eventUtility.DisableEventHandlers();
										SPModerationStatusType status = actionListItem.ModerationInformation.Status;
										actionListItem.File.SaveBinary(replacementFileBytes);
                                        actionListItem.File.MoveTo(actionListItem.File.ParentFolder.Url + "/" + replacementFileName);
										actionListItem = actionListItem.ParentList.GetItemById(actionListItem.ID);
										if (actionListItem.ModerationInformation.Status != status)
										{
											actionListItem.ModerationInformation.Status = status;
											actionListItem.Update();
										}
										if (fileNameChanged)
										{	
											actionListItem.SlamUpdate(false, false, false);
										}
										eventUtility.EnableEventHandlers();
									}
								}
							}
						}

					});

					Page page = HttpContext.Current.Handler as Page;
					if (page != null)
					{
						page.ClientScript.RegisterClientScriptInclude("jquery", page.ResolveUrl("~/_layouts/inc/jquery-1.6.2.min.js"));

						string script = String.Format("<script type=\"text/javascript\">{0}$('document').ready(function a(){{{1}}});</script>", DocumentReplacementReadyScript("Name", context.FieldControl), DocumentReplacementButtonsScript("Name", context.FieldControl));
						page.ClientScript.RegisterClientScriptBlock(this.GetType(), "DocumentReplacementUpload", script);
					}
				}
			}
		}

		#region RegisterDocumentReplacementUploadFieldAction Methods

		private string DocumentReplacementReadyScript(string fieldName, Control enhacedUpload)
		{
			StringBuilder builder = new StringBuilder("");

			builder.Append(String.Format(@"function ShowUploadControl()
											{{
												$('#{0}').parent().parent().parent().parent().show();
												$('input[Title=\'{1}\']').parent().parent().parent().parent().hide();
											}}", enhacedUpload.Controls[0].Controls[1].ClientID, fieldName));

			builder.Append(String.Format(@"function HideUploadControl()
														{{
															$('#{0}').parent().parent().parent().parent().hide();
															$('input[Title=\'{1}\']').parent().parent().parent().parent().show();
															if($('#{0} .RemoveIcon').length > 0)
																$('#{0} .RemoveIcon').trigger('click');
														}}", enhacedUpload.Controls[0].Controls[1].ClientID, fieldName));

			return builder.ToString();
		}

		private string DocumentReplacementButtonsScript(string fieldName, Control enhacedUpload)
		{
			StringBuilder builder = new StringBuilder("");

			builder.Append("var btnReplace = '<input id=\"btnReplaceDocument\" style=\"margin-left:10px\" type=\"button\" value=\"Replace\" onClick=\"ShowUploadControl();\">';");
			builder.Append("var btnCancel = '<input id=\"btnCancelReplaceDocument\" type=\"button\" value=\"Cancel\" onClick=\"HideUploadControl();\">';");

			builder.Append(String.Format("$('input[Title=\"{0}\"]').parent().append(btnReplace);", fieldName));
			builder.Append(String.Format("$('#{0} .btnCancelUpload').parent().append(btnCancel);", enhacedUpload.Controls[0].Controls[1].ClientID));
			// Bind the events when the uploader is loaded.
			builder.Append(String.Format("settings_{0}.uploader.bind('PostInit',HideUploadControl());", enhacedUpload.ClientID));

			return builder.ToString();
		}

	}


	


	#endregion
}
